﻿using System;
using System.Collections.Generic;
using System.Linq;
using ASPNETMVCApplication.ActionServiceReference;
using ASPNETMVCApplication.Areas.Shop;
using ASPNETMVCApplication.Repositories.Core;

namespace ASPNETMVCApplication.Repositories
{
    /// <summary>
    /// Product Repository.
    /// </summary>
    public class ProductRepository : RepositoryBase, IProductRepository
    {
        /// <summary>
        /// Gets list of products.
        /// </summary>
        /// <param name="criterion"></param>
        /// <returns></returns>
        public List<Product> GetList(Criterion criterion = null)
        {
            var request = new ProductRequest().Prepare();

            request.LoadOptions = new string[] { "Products" };
            request.Criteria = new ProductCriteria
            {
                CategoryId = int.Parse(criterion.Filters.Single(f => f.Attribute == "CategoryId").Operand.ToString()),
                SortExpression = criterion.OrderByExpression
            };

            var response = Client.GetProducts(request);

            Correlate(request, response);

            return response.Products == null ? null : response.Products.ToList();
        }

        public List<Product> Search(int categoryId, string sort, string order)
        {
            var request = new ProductRequest().Prepare();

            request.LoadOptions = new string[] { "Search" };



            request.Criteria = new ProductCriteria
            {
                CategoryId = categoryId,
                SortExpression = sort + " " + order
            };

            var response = Client.GetProducts(request);

            Correlate(request, response);

            return response.Products.ToList();
        }

        public void Update(Product product)
        {
            var request = new ProductRequest().Prepare();
            request.Action = "Update";
            request.Product = product;

            var response = Client.SetProducts(request);

            Correlate(request, response);

            // These messages are for public consumption. Includes validation errors.
            if (response.Acknowledge == AcknowledgeType.Failure)
                throw new ApplicationException(response.Message);
        }

        /// <summary>
        /// Gets a product by productId.
        /// </summary>
        /// <param name="productId"></param>
        /// <returns></returns>
        public Product Get(int productId, int categoryId)
        {
            var request = new ProductRequest().Prepare();
            request.LoadOptions = new string[] { "Product" };
            request.Criteria = new ProductCriteria { ProductId = productId, CategoryId = categoryId };

            var response = Client.GetProducts(request);

            Correlate(request, response);

            return response.Product;
        }

        public Product Get(int productId)
        {
            var request = new ProductRequest().Prepare();
            request.LoadOptions = new string[] { "Product" };
            request.Criteria = new ProductCriteria { ProductId = productId };

            var response = Client.GetProducts(request);

            Correlate(request, response);

            return response.Product;
        }

        #region Not implemented members

        public int GetCount(Criterion criterion = null)
        {
            throw new NotImplementedException();
        }

        // TAIPM : 04/01/2011
        // Implementation Insert Product
        // Must to update ProductRequest
        public void Insert(Product product)
        {
            var request = new ProductRequest().Prepare();
            request.Action = "Create";
            request.Product = product;

            var response = Client.SetProducts(request);

            Correlate(request, response);

            // These messages are for public consumption. Includes validation errors.
            if (response.Acknowledge == AcknowledgeType.Failure)
                throw new ApplicationException(response.Message);
        }

        public void Delete(int productId)
        {
            var request = new ProductRequest().Prepare();
            request.Action = "Delete";
            request.Product = new Product { ProductId = productId };

            var response = Client.SetProducts(request);

            Correlate(request, response);
        }

        public void DeleteByCategoryId(int categoryId)
        {
            var request = new ProductRequest().Prepare();
            request.Action = "DeleteByCategoryId";
            request.CategoryId = categoryId;

            var response = Client.SetProducts(request);

            Correlate(request, response);
        }
        /// <summary>
        /// Updates an existing product.
        /// </summary>
        /// <param name="customer"></param>
        

       

        /// <summary>
        /// Book an existing product.
        /// </summary>
        /// <param name="customer"></param>
        public void Book(int productId, int statusId)
        {
            var request = new ProductRequest().Prepare();
            request.Action = "Book";
            request.Criteria.StatusId = statusId;

            var response = Client.SetProducts(request);

            Correlate(request, response);

            // These messages are for public consumption. Includes validation errors.
            if (response.Acknowledge == AcknowledgeType.Failure)
                throw new ApplicationException(response.Message);
        }

        

        public void Dispose()
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}